#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>

#define PAREDES 1
#define CHAO 2
#define MOLDURA 3
#define SPOT 4
#define LUMINARIA 5
#define BANCO 6
#define SUPORTE 7
#define VASO 8

int Rotate = 0,
	Scaling = 0,
	Translate = 0,
	Camera = 0;

double s[3] = {1, 1, 1};
double t[3] = {0, 0, 0};
double r[3] = {0, 0, 0};
double c[3] = {0, 0, 0};
int angle = 0;

/*Flags para luminarias spots*/
int spot1On = 0,
	spot2On = 0,
	spot3On = 0;

/*Flags para iluminação ambiente*/
int outsideOn = 1;
int outsidePower = 5;

/*Flags para luminaria central*/
int on = 1;
int intensidade = 1.5;

/*Valor associado para cada textura utilizada*/
GLuint texture[3];

/*Variáveis da câmera - descrevem a posição, a direção de observação e os ângulos de azimute*/
float angulo = 0,
	theta = 0,
	xCamPos = 0,
	yCamPos = 0,
	zCamPos = 0,
	xCamFocus,
	yCamFocus,
	zCamFocus;
	

/*Função que carrega a textura*/
GLuint LoadTextureRAW(const char * filename){
  GLuint texture;
  int width, height;
  GLubyte * data;
  FILE * file;

  file = fopen(filename, "rb");
  if ( file == NULL ) return 0;

  width = 512;
  height = 512;
  data = (GLubyte*)malloc(width * height * 3);

  fread(data, width * height * 3, 1, file);
  fclose(file);

  glGenTextures(1, &texture);

  glBindTexture(GL_TEXTURE_2D, texture);

  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );

  free(data);

  return texture;
}

/*Funcao que pula as três primeiras linhas dos arquivos .obj*/
void skipInit(FILE *arq) {

	size_t size = 50;
	char *linha = malloc(size);
	int i;

	for(i=0; i<3; i++)
		getline(&linha, &size, arq);

}

/*Funcao que recebe um arquivo e as cores de um objeto*/
void createObject(char object[], double r, double g, double b) {

	FILE *arq;
	char currentCh;
	char useless[80];
	int numVertices = 0, numFaces = 0;

	//Abre o arquivo de pontos e faces de um objeto
	arq = fopen( object, "r");

	skipInit(arq);

	//Salva o número de faces e vértices de um objeto
	while ((currentCh = getc(arq)) != EOF){

	    if (currentCh == 'v') numVertices++;
	    if (currentCh == 'f') numFaces++;

	}

	/*Cria matrizes de vertices, faces e normais*/
	double vertices[numVertices][3];
	int faces[numFaces][3];
	double normals[numVertices][3];

	/*Retorna ao começo do arquivo*/
	rewind(arq);

	skipInit(arq);

	int i = 0, j = 0;
	double x, y, z;
	while(j != numFaces) {
		fscanf(arq, "%s %lf %lf %lf\n", useless, &x, &y,&z );
		if(useless[0] == 'v') {
				vertices[i][0] = x;
				vertices[i][1] = y;
				vertices[i][2] = z;
				i++;
		}
		else if(useless[0] == 'f') {
				faces[j][0] = x;
				faces[j][1] = y;
				faces[j][2] = z;
				j++;
		}

	}

	/*Salva a normal dos vertices na matrix de normais*/
	for(i=0; i<numVertices; i++){
		double sum = 0;
		int j=0;

		for(j=0; j<3; j++) sum += vertices[i][j]*vertices[i][j];

		sum = sqrt(sum);
		if(sum > 0) for(j=0; j<3; j++) normals[i][j] = vertices[i][j]/sum;
	}

	glMatrixMode(GL_MODELVIEW);

	float k[] = {r, g, b, 1.0};
	float k2[] = {r-0.2, g-0.2, b-0.2, 1.0};

	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, k2);
	
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, k);
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40);

	/*Gera as faces com os vértices e suas normais*/
	for(i=0; i<numFaces; i++){
		glBegin(GL_TRIANGLES);
			glNormal3dv(normals[faces[i][0]-1]);
			glVertex3dv(vertices[faces[i][0]-1]);
			glNormal3dv(normals[faces[i][1]-1]);
			glVertex3dv(vertices[faces[i][1]-1]);
			glNormal3dv(normals[faces[i][2]-1]);
			glVertex3dv(vertices[faces[i][2]-1]);
		glEnd();
	}

    fclose(arq);

}


/*Funcao auto-explicativa*/
void createDisplayLists(){

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glNewList(PAREDES, GL_COMPILE);
		createObject("objetos/estrutura.obj", 0.968627, 0.964706, 0.964706);
	glEndList();
	glNewList(CHAO, GL_COMPILE);
		createObject("objetos/chao.obj", 0.3,0.3,0.3);
	glEndList();
	glNewList(MOLDURA, GL_COMPILE);
		createObject("objetos/moldura.obj", 0.894118, 0.592157, 0.113725);
	glEndList();
	glNewList(SPOT, GL_COMPILE);
		createObject("objetos/luminariaSpot.obj", 0.5, 0.5, 0.5);
	glEndList();
	glNewList(LUMINARIA, GL_COMPILE);
		createObject("objetos/luminariaAmbiente.obj", 0.5, 0.5, 0.5);
	glEndList();
	glNewList(BANCO, GL_COMPILE);
		createObject("objetos/banco.obj", 0.705882, 0.388235, 0.388235);
	glEndList();
	glNewList(SUPORTE, GL_COMPILE);
		createObject("objetos/suporte.obj", 0.596078, 0.043137, 0.043137);
	glEndList();
	glNewList(VASO, GL_COMPILE);
		createObject("objetos/vaso.obj", 0.7, 0.7, 0.5);
	glEndList();


}

/*Funcao que monitora eventos de teclado*/
void key( unsigned char k, int x, int y ){

	if( k == 'r') if(Rotate == 0) {Camera=0;Rotate = 1; Scaling = 0; Translate = 0;}       //Entra no modo de rotação
	if( k == 's') if(Scaling == 0) {Camera=0;Scaling = 1; Rotate = 0; Translate = 0;}      //Entra no modo de escalonamento
	if( k == 't') if(Translate == 0) {Camera=0;Translate = 1; Scaling = 0; Rotate = 0;}    //Entra no modo de translação
	if( k == 'c') if(Camera == 0) {Camera=1;Translate = 0; Scaling = 0; Rotate = 0;}
	

	if(k == 'q'){exit(0);} //Sai do programa


	/*Teclas que ligam e desligam as luzes*/
	if(k=='y'){
		if(on == 1) {
			intensidade = 25;
			on = 0;
			glutPostRedisplay();
		}
		else {
			intensidade = 1.5;
			on = 1;
			glutPostRedisplay();
		}
	}
	if(k=='u'){
		if(outsideOn == 1) {
			outsidePower = 50;
			outsideOn = 0;
			glutPostRedisplay();
		}
		else {
			outsidePower = 5;
			outsideOn = 1;
			glutPostRedisplay();
		}

	}
	if(k=='i'){
		if(spot1On == 1) {
			spot1On = 0;
			glutPostRedisplay();
		}
		else {
			spot1On = 1;
			glutPostRedisplay();
		}

	}
	if(k=='o'){
		if(spot2On == 1) {
			spot2On = 0;
			glutPostRedisplay();
		}
		else {
			spot2On = 1;
			glutPostRedisplay();
		}

	}
	if(k=='p'){
		if(spot3On == 1) {
			spot3On = 0;
			glutPostRedisplay();
		}
		else {
			spot3On = 1;
			glutPostRedisplay();
		}

	}


	

/*Teclas da câmera*/

	/*A câmera olha para cima*/
	if (k == '7'){
		theta -= (1.5*3.1415)/180;
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		yCamFocus = yCamPos - 2*sin(theta);
		glutPostRedisplay();
	}

	/*A câmera olha para baixo*/
	if(k == '4'){
		theta += (1.5*3.1415)/180;
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		yCamFocus = yCamPos - 2*sin(theta);
		glutPostRedisplay();
	}

	/*A câmera move-se para frente*/
	if (k == '5'){
		xCamPos -= 1*cos(theta)*sin(angulo);
		zCamPos -= 1*cos(theta)*cos(angulo);
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		glutPostRedisplay();
	}

	/*A câmera move-se para trás*/
	if (k == '2'){
		xCamPos += 1*cos(theta)*sin(angulo);
		zCamPos += 1*cos(theta)*cos(angulo);
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		glutPostRedisplay();
	}

	/*A câmera se eleva*/
	if (k == '9'){
		yCamPos += 0.2;
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		yCamFocus = yCamPos - 2*sin(theta);
		glutPostRedisplay();
	}

	/*A câmera se abaixa*/
	if (k=='6'){
		yCamPos -= 0.2;
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		yCamFocus = yCamPos - 2*sin(theta);
		glutPostRedisplay();
	}

	/*A câmera olha para a esquerda*/
	if (k=='1'){
		angulo += (1.5*3.1415)/180;
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		yCamFocus = yCamPos - 2*sin(theta);
		glutPostRedisplay();
	}

	/*A câmera olha para a direita*/
	if (k=='3'){
		angulo -= (1.5*3.1415)/180;
		xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
		zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
		yCamFocus = yCamPos - 2*sin(theta);
		glutPostRedisplay();
	}


}

/*Funcao que monitora eventos de teclado especiais*/
void specialKey(int k, int x, int y){

	if(k == GLUT_KEY_F1) {Rotate = 0; Scaling = 0; Translate = 0;} //Sai do modo de rotação, escalonamento ou translação

	/*Teclas dos modos de edição*/
	if(k == GLUT_KEY_UP){
		if(Rotate == 1) {
			angle += 2;
			r[0] = 1;
			r[1] = 0;
			r[2] = 0;
			printf("%d %lf %lf %lf\n", angle, r[0], r[1], r[2]);
			glutPostRedisplay();
		}
		if(Scaling == 1){
			s[0] += 0.1;
			s[1] += 0.1;
			s[2] += 0.1;
			printf("%lf %lf %lf\n", s[0], s[1], s[2]);
			glutPostRedisplay();
		}
		if(Translate == 1){
			t[1] += 0.2;
			printf("%lf %lf %lf\n", t[0], t[1], t[2]);
			glutPostRedisplay();
		}
		if(Camera == 1){
			c[1] += 1;
			glutPostRedisplay();
		}

	}
	if(k == GLUT_KEY_DOWN){
		if(Rotate == 1) {
			angle -= 2;
			r[0] = 1;
			r[1] = 0;
			r[2] = 0;
			printf("%d %lf %lf %lf\n", angle, r[0], r[1], r[2]);
			glutPostRedisplay();
		}
		if(Scaling == 1){
			s[0] -= 0.1;
			s[1] -= 0.1;
			s[2] -= 0.1;
			printf("%lf %lf %lf\n", s[0], s[1], s[2]);
			glutPostRedisplay();
		}
		if(Translate == 1){
			t[1] -= 0.2;
			printf("%lf %lf %lf\n", t[0], t[1], t[2]);
			glutPostRedisplay();
		}
		if(Camera == 1){
			c[1] -= 1;
			glutPostRedisplay();
		}

	}
	if(k == GLUT_KEY_RIGHT){
		if(Rotate == 1) {
			angle += 2;
			r[0] = 0;
			r[1] = 1;
			r[2] = 0;
			printf("%d %lf %lf %lf\n", angle, r[0], r[1], r[2]);
			glutPostRedisplay();
		}
		if(Translate == 1){
			t[0] += 0.2;
			printf("%lf %lf %lf\n", t[0], t[1], t[2]);
			glutPostRedisplay();
		}
		if(Camera == 1){
			c[0] += 1;
			glutPostRedisplay();
		}

	}
	if(k == GLUT_KEY_LEFT){
		if(Rotate == 1) {
			angle -= 2;
			r[0] = 0;
			r[1] = 1;
			r[2] = 0;
			printf("%d %lf %lf %lf\n", angle, r[0], r[1], r[2]);
			glutPostRedisplay();
		}
		if(Translate == 1){
			t[0] -= 0.2;
			printf("%lf %lf %lf\n", t[0], t[1], t[2]);
			glutPostRedisplay();
		}
		if(Camera == 1){
			c[0] -= 1;
			glutPostRedisplay();
		}
	}
	if(k == GLUT_KEY_F3){
		if(Rotate == 1) {
			angle += 2;
			r[0] = 0;
			r[1] = 0;
			r[2] = 1;
			printf("%d %lf %lf %lf\n", angle, r[0], r[1], r[2]);
			glutPostRedisplay();
		}
		if(Translate == 1){
			t[2] += 0.2;
			printf("%lf %lf %lf\n", t[0], t[1], t[2]);
			glutPostRedisplay();
		}
		if(Camera == 1){
			c[2] += 1;
			glutPostRedisplay();
		}

	}
	if(k == GLUT_KEY_F2){
		if(Rotate == 1) {
			angle -= 2;
			r[0] = 0;
			r[1] = 0;
			r[2] = 1;
			printf("%d %lf %lf %lf\n", angle, r[0], r[1], r[2]);
			glutPostRedisplay();
		}
		if(Translate == 1){
			t[2] -= 0.2;
			printf("%lf %lf %lf\n", t[0], t[1], t[2]);
			glutPostRedisplay();
		}
		if(Camera == 1){
			c[2] -= 1;
			glutPostRedisplay();
		}
	}


}

/*Carrega os arquivos de imagem na textura*/
void loadTextures() {
	texture[0] = LoadTextureRAW("imagens/cezanne.raw");
	texture[1] = LoadTextureRAW("imagens/munch.raw");
	texture[2] = LoadTextureRAW("imagens/gogh.raw");
}

/*Inicializa os valores para a execução do programa*/
void myInit(){

	loadTextures();
	glClearColor(0,0,0, 1);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60, 1, 0.1, 150.0);
	glMatrixMode(GL_MODELVIEW);
	createDisplayLists();

}

/*Renderiza os objetos na tela*/
void display(){

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glClear(GL_COLOR_BUFFER_BIT);

	glEnable(GL_DEPTH_TEST);
	xCamFocus = xCamPos - 2*cos(theta)*sin(angulo);
	zCamFocus = zCamPos - 2*cos(theta)*cos(angulo);
	yCamFocus = yCamPos - 2*sin(theta);
	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
	glClear( GL_DEPTH_BUFFER_BIT );

	glShadeModel(GL_SMOOTH);

	glEnable(GL_DEPTH_TEST);

/*Iluminação*/

	GLfloat light_pos0[] = {0,0, 25, 1.0};
	GLfloat light_pos1[] = {0, 17, 8, 1.0};
	GLfloat diffuse[] = {2, 2, 2, 1.0};
	GLfloat ambient[] = {0.9, 0.9, 0.9, 1.0};
	GLfloat specular[] = {0.7, 0.7, 0.7, 1.0};

	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

/*Iluminação externa*/
	glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, outsidePower);


	glLightfv(GL_LIGHT0, GL_POSITION, light_pos0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
/*Iluminação externa*/

/*Luminaria central*/
	glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, intensidade);

	glLightfv(GL_LIGHT1, GL_POSITION, light_pos1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
/*Luminaria central*/

	GLfloat spotAmbient[] = {0.8, 0.8, 0.8, 1.0};
	GLfloat spotDiffuse[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat spotSpecular[] = {1.0, 1.0, 1.0, 1.0};
	

/*SPOT 1 - ESQUERDA*/
	GLfloat spot1Position[] = {0, 1, 0, 1.0};
	GLfloat spot1Dir [] = {-1, 0, 0};

	glLightfv(GL_LIGHT2, GL_POSITION, spot1Position);
	glLightfv(GL_LIGHT2, GL_DIFFUSE, spotDiffuse);
	glLightfv(GL_LIGHT2, GL_AMBIENT, spotAmbient);
	glLightfv(GL_LIGHT2, GL_SPECULAR, spotSpecular);

	glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 0.2);

	glLightf (GL_LIGHT2, GL_SPOT_CUTOFF, 45.0);
	glLightfv (GL_LIGHT2, GL_SPOT_DIRECTION, spot1Dir);
	glLightf (GL_LIGHT2, GL_SPOT_EXPONENT, 50.0);
/*SPOT 1 - ESQUERDA*/

/*SPOT 2 - CENTRAL*/
	GLfloat spot2Position[] = {0, 2, -1, 1.0};
	GLfloat spot2Dir [] = {0, 0, -1};

	glLightfv(GL_LIGHT3, GL_POSITION, spot2Position);
	glLightfv(GL_LIGHT3, GL_DIFFUSE, spotDiffuse);
	glLightfv(GL_LIGHT3, GL_AMBIENT, spotAmbient);
	glLightfv(GL_LIGHT3, GL_SPECULAR, spotSpecular);

	glLightf(GL_LIGHT3, GL_CONSTANT_ATTENUATION, 0.3);

	glLightf (GL_LIGHT3, GL_SPOT_CUTOFF, 45.0);
	glLightfv (GL_LIGHT3, GL_SPOT_DIRECTION, spot2Dir);
	glLightf (GL_LIGHT3, GL_SPOT_EXPONENT, 50.0);
/*SPOT 2 - CENTRAL*/

/*SPOT 3 - DIREITA*/
	GLfloat spot3Position[] = {0, 1, 0, 1.0};
	GLfloat spot3Dir [] = {1, 0, 0};

	glLightfv(GL_LIGHT4, GL_POSITION, spot3Position);
	glLightfv(GL_LIGHT4, GL_DIFFUSE, spotDiffuse);
	glLightfv(GL_LIGHT4, GL_AMBIENT, spotAmbient);
	glLightfv(GL_LIGHT4, GL_SPECULAR, spotSpecular);

	glLightf(GL_LIGHT4, GL_CONSTANT_ATTENUATION, 0.2);

	glLightf (GL_LIGHT4, GL_SPOT_CUTOFF, 45.0);
	glLightfv (GL_LIGHT4, GL_SPOT_DIRECTION, spot3Dir);
	glLightf (GL_LIGHT4, GL_SPOT_EXPONENT, 50.0);
/*SPOT 3 - DIREITA*/

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);

	if(spot1On == 1) {glEnable(GL_LIGHT2);}
	else{glDisable(GL_LIGHT2);}

	if(spot2On == 1) {glEnable(GL_LIGHT3);}
	else{glDisable(GL_LIGHT3);}

	if(spot3On == 1) {glEnable(GL_LIGHT4);}
	else{glDisable(GL_LIGHT4);}

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);

/*Objetos*/

/*PAREDES*/
	glScalef(20, 20,20);
	glCallList(PAREDES);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*PAREDES*/

/*CHÃO*/
	glScalef(20, 20,20);
	glCallList(CHAO);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*CHÃO*/

/*MOLDURA CENTRAL*/
	glTranslatef(0,0,-50);
	glScalef(3, 3, 3);
	glCallList(MOLDURA);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*MOLDURA CENTRAL*/

/*MOLDURA ESQUERDA*/
	glTranslatef(-34.6,0,0);
	glRotatef(90, 0, 1, 0);
	glScalef(3, 3, 3);
	glCallList(MOLDURA);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*MOLDURA ESQUERDA*/

/*MOLDURA DIREITA*/
	glTranslatef(34.6,0,0);
	glRotatef(-90, 0, 1, 0);
	glScalef(3, 3, 3);
	glCallList(MOLDURA);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*MOLDURA DIREITA*/

/*SPOT CENTRAL*/
	glTranslatef(0,16.8,-27);
	glScalef(3, 3, 3);
	glCallList(SPOT);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*SPOT CENTRAL*/

/*SPOT ESQUERDA*/
	glTranslatef(-14,16.8,0);
	glRotatef(90, 0, 1, 0);
	glScalef(3, 3, 3);
	glCallList(SPOT);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*SPOT ESQUERDA*/

/*SPOT DIREITA*/
	glTranslatef(14,16.8,0);
	glRotatef(-90, 0, 1, 0);
	glScalef(3, 3, 3);
	glCallList(SPOT);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*SPOT DIREITA*/

/*LUMINARIA CENTRAL*/
	glTranslatef(0.2, 19, 0);
	glRotatef(90, 0, 1, 0);
	glScalef(2, 2, 2);
	glCallList(LUMINARIA);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*LUMINARIA CENTRAL*/

/*BANCO*/
	glTranslatef(0, -15.8, -26);
	glScalef(3, 3, 3);
	glCallList(BANCO);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*BANCO*/

/*SUPORTE*/
	glTranslatef(0, -15.8, 0);
	glScalef(5, 8, 5);
	glCallList(SUPORTE);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*SUPORTE*/

/*VASO*/
	glTranslatef(-0.2, -11.8, 0);
	glScalef(5, 5, 5);
	glCallList(VASO);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*VASO*/

/*Texturas*/

/*QUADRO 1 - CEZANNE*/
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[0]);

	glPushMatrix();
	glTranslatef(-34.2, 0, 0);
	glRotatef(-90, 0, 1, 0);
	glRotatef(180, 0, 0, 1);
	glScalef(4.9, 7.5, 4.9);
	glBegin( GL_QUADS );
		glTexCoord2d(0.0,0.0); glVertex3d(-1.0,-1.0,0);
		glTexCoord2d(1.0,0.0); glVertex3d(1.0,-1.0,0);		glTexCoord2d(1.0,1.0); glVertex3d(1.0,1.0,0);
		glTexCoord2d(0.0,1.0); glVertex3d(-1.0,1.0,0);
	glEnd();
	glDisable(GL_TEXTURE_2D);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*QUADRO 1 - CEZANNE*/

/*QUADRO 2 - MUNCH*/
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[1]);

	glPushMatrix();
	glTranslatef(0, 0,-49.6);
	glRotatef(180, 0, 1, 0);
	glRotatef(180, 0, 0, 1);
	glScalef(4.9, 7.5, 4.9);
	glBegin( GL_QUADS );
		glTexCoord2d(0.0,0.0); glVertex3d(-1.0,-1.0,0);
		glTexCoord2d(1.0,0.0); glVertex3d(1.0,-1.0,0);		glTexCoord2d(1.0,1.0); glVertex3d(1.0,1.0,0);
		glTexCoord2d(0.0,1.0); glVertex3d(-1.0,1.0,0);
	glEnd();
	glDisable(GL_TEXTURE_2D);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*QUADRO 2 - MUNCH*/

/*QUADRO 3 - GOGH*/
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[2]);

	glPushMatrix();
	glTranslatef(34.2, 0, 0);
	glRotatef(90, 0, 1, 0);
	glRotatef(180, 0, 0, 1);
	glScalef(4.9, 7.5, 4.9);
	glBegin( GL_QUADS );
		glTexCoord2d(0.0,0.0); glVertex3d(-1.0,-1.0,0);
		glTexCoord2d(1.0,0.0); glVertex3d(1.0,-1.0,0);		glTexCoord2d(1.0,1.0); glVertex3d(1.0,1.0,0);
		glTexCoord2d(0.0,1.0); glVertex3d(-1.0,1.0,0);
	glEnd();
	glDisable(GL_TEXTURE_2D);

	glLoadIdentity();

	gluLookAt(xCamPos, yCamPos, zCamPos, xCamFocus, yCamFocus, zCamFocus, 0.0, 1.0, 0.0);
/*QUADRO 3 - GOGH*/

	glutSwapBuffers();

	/*glTranslatef(t[0], t[1], t[2]);
	glRotatef(angle, r[0], r[1], r[2]);
	glScalef(s[0], s[1], s[2]);*/

}

/*Função principal*/
int main(int argc, char **argv){

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(700, 700);
	glutInitWindowPosition(0,0);
	glutCreateWindow("Galeria");
	glutKeyboardFunc(key);
	glutSpecialFunc(specialKey);
	myInit();
	glutDisplayFunc(display);
	glutMainLoop();

	return(0);
}

